perm filename SYS1.FAI[CMS,LCS] blob
sn#363975 filedate 1978-06-23 generic text, type T, neo UTF8
00100 ;Floppy disk directory routines.
00200 .INSERT ASMBL.FAI[CMS,LCS]
00300 .INSERT SYSDEF.FAI[CMS,LCS]
00400
00500 ZERO ← 274 ;Fail offset
00600
00700 LOC ZERO+21
00800 CHR: 0 ;Shifter temp. reg.
00900 0 ;CUR
01000 0
01100 SHFLOC: 0 ;Shift lock bit
01200 STOP: JMP STOP ;Go nowhere fast.
01300 FLAD: 0 ;Disk buffer pointer
01400 0
01500 XU: 0 ;Exec mode
01600 WFOPEN: 0 ;Write file open flag
01700 OSEC: 0
01800 FLEN: 0
01900 UFLG: 0 ;Program interrupt enable flag.
02000 MFLG: 0 ;Modem / SI/O flag.
02100
02200 LOC ZERO+40
02300 FBLK: 0 ;File block
02400 FNAM: BLOCK 11 ;9 Chr file name.
02500 FTRK: 0 ;Disk track number
02600 FSEC: 0 ;Disk sector number
02700 NSEC: 0 ;Number of sectors
02800
02900 LOC ZERO+60
03000 DBUF: 0 ;Directory buffer
03100 SCNT: 0 ;Number of sectors
03200 FCNT: 0 ;Number of files
03300 FFDIR: 0 ;First free directory block
03400 FFTRK: 0 ;First free track
03500 FFSEC: 0 ;First free sector
00100 LOC ZERO+100
00200 PCHR: CMPI 12 ;<lf>
00300 BEQ LF
00400 CMPI 14 ;<home> Key on S720 keyboard.
00500 BNE CKCR
00600 LF: CLC
00700 LDAZ CUR
00800 ADCI 100 ;Next line
00900 STAZ CUR
01000 BCC CLIN
01100 INCZ 23 ;CUR+1
01200 LDAZ 23 ;CUR+1
01300 CMPI 210 ;End of DPY mem.
01400 BNE CLIN
01500 LDAI 200
01600 STAZ 23 ;CUR+1
01700 CLIN: LDYI 77
01800 LDAI 40
01900 CLOOP: STAIY CUR ;Clear line
02000 DEY
02100 BPL CLOOP
02200 BMI CJUMP ;Update cursor
02300
02400 CKCR: CMPI 15 ;<cr>
02500 BNE CKBS
02600 CR: LDAZ CUR
02700 ANDI 300
02800 STAZ CUR
02900 CJUMP: JMP UPCUR ;Update cursor
03000
03100 CKBS: CMPI 10 ;<BS>
03200 BNE JPIT
03300 JMP BS
03400 JPIT: JMP PIT ;Print it
00100 LOC ZERO+200
00200 FBUF: ;Disk buffer
00300 STAR: LDAI 14 ;Reset display
00400 STA DPYRAS
00500 LDAI 377
00600 STA DPYROW
00700 LDAI 120 ;Default display control bits.
00800 STA DPYCON
00900 LDAI 4
01000 STA DPYMUX
01100 LDAI 15
01200 STA KBC
01300 LDAI 15 ;Baud rate generator
01400 STA BRG0
01500 STA BRG1
01600 LDXI 3 ;Reset ACIA
01700 STX ACIAC
01800 STA ACIAC ;Control word
01900
02000 LDXI 2
02100 IDLMOV: LDAZX IJMP
02200 STAZX STOP
02300 DEX
02400 BPL IDLMOV
02500
02600 LDAI 200 ;Setup display cursor
02700 STAZ CURH
02800
02900 CLI
03000 IJMP: JMP STOP
00100 LOC ZERO+1000
00200 RLOC ← 2 ;High byte of origin address
00300
00400 IRQV: STAZ 3 ;IRQ vector. Save A
00500 JMP IPOLL
00600
00700 NMIV: PLA ;Non maskable interupt vector
00800 PLA ;Flush stack
00900 PLA
01000
01100 LDXI 0 ;For ENDSK
01200 JSR ENDSK ;Reset disk, timer. Read status
01300 JMP RERR ;Return with error
01400
01500 IPOLL: BIT KBC ;Check if keyboard
01600 BMI RKEY
01700 JMP 177432 ;Jump to DDT
01800
01900 RKEY: PHA ;Save registers
02000 TYA
02100 PHA
02200 TXA
02300 PHA
02400
02500 LDA KBD ;Read keyboard
02600
02700 CMPI 352 ;<Clear>
02800 BNE CKX
02900 STAZ XU ;Set exec.
03000 JSR PCHR ;Echo it.
03100
03200 JSR CR ;<cr>
03300 LDAI 12 ;<lf>
03400 STAZ UFLG ;Disable program interrupts.
03500 ECHO: JSR PCHR
03600 JMP RTRN
03700
03800 CKX: BITZ XU ;Check mode
03900 BMI EXEC
04000 BITZ UFLG ;Check if program int.
04100 BPL ECHO
04200 JMP TTYO
00100 EXEC: CMPI 15 ;<cr>
00200 BNE ECHO
00300
00400 JSR PCHR ;Echo it
00500 LDYI 12 ;Number of chrs+1 in FNAM
00600 NLOOP: LDAIY CUR ;Save file name in FNAM
00700 STAY 37 ;FBLK-1
00800 DEY
00900 BNE NLOOP
01000
01100 CMPI 40 ;Check for <space>
01200 BEQ GCMD
01300 LDAI 77 ;"α
01400 BNE NOSPC
01500
01600 GCMD: LDAIY CUR ;Get command
01700
01800 NOSPC: PHA
01900 LDAI FMARK ;Setup file mark
02000 STAZ FBLK
02100 JSR LF ;Print <lf>.
02200 PLA
00100 CMPI "T" ;Type file
00200 BNE CKWRT
00300
00400 JSR OPIN
00500 BNE XERR
00600 JSR DPYDSK ;Setup disk load address
00700 RIT: JSR READ ;Read the file
00800 JMP ECK ;Check for error
00900
01000 CKWRT: CMPI "W" ;Save screen
01100 BNE CKLOAD
01200
01300 LDAI 20 ;File length in sectors.
01400 JSR ENTR
01500 BNE XERR
01600 JSR DPYDSK ;Setup disk write address
01700 BNE WIT ;Write it
01800
01900 CKLOAD: CMPI "L" ;Load file
02000 BNE CKRUN
02100
02200 JSR OPIN
02300 BNE XERR
02400 JSR ADRSET ;Setup disk read address
02500 BNE RIT ;Jump and load it
02600
02700 CKRUN: CMPI "R" ;Run program
02800 BNE CKUN
02900
03000 JSR OPIN
03100 BNE XERR
03200 JSR ADRSET ;Setup disk read address
03300 JSR READ ;Load file
03400 BNE XERR ;Check for error
03500
03600 UMEM ← FBUF ;Until more memory
03700 JMP UMEM ;Jump to program
03800
03900 CKUN: CMPI "U" ;Unload
04000 BNE XERR ;Exec. error
04100
04200 LDAI 1 ;File length in sectors.
04300 JSR ENTR
04400 BNE XERR
04500 JSR DPYDSK ;Setup disk write address
04600 JSR XONE ;Until more memory
04700 WIT: JSR WRITE ;Write it
04800 BNE XERR
04900 JSR CLOZE
05000 ECK: BEQ XOFF ;Jump if no error
05100 XERR: LDAI 77 ;Print
05200 JSR PCHR
05300
05400 XOFF: LDAI 0
05500 STAZ XU ;Reset XU
05600
05700 RTRN: PLA
05800 TAX
05900 PLA
06000 TAY
06100 PLA
06200 RTI ;Return
00100 DPYDSK: LDAI 200 ;Setup disk buffer address
00200 STAZ 31 ;FLAD+1
00300 ASLA ;Clear A
00400 STAZ FLAD
00500 LDXI 20 ;16 sectors.
00600 XSET: STXZ NSEC
00700 RTS
00800
00900 ADRSET: LDAI 200 ;Setup disk buffer address
01000 STAZ FLAD
01100 ASLA ;Clear A
01200 STAZ 31 ;FLAD+1
01300 XONE: LDXI 1 ;X=1 For one sector
01400 BNE XSET
00100 DMARK ← 74 ;Directory mark
00200 FMARK ← 72 ;File mark
00300
00400 LOKUP: JSR FWAI ;Check if disk busy
00500 LDAI 364 ;Restore track 0
00600 STA FDSKC
00700 JSR FWAI
00800
00900 LDAI 375 ;Second sector
01000 STA FDSKS
01100 JSR RBUF ;Load one sector into FBUF
01200 BNE NOHED ;Check for read error
01300
01400 LDAZ FBUF ;Check for directory mark
01500 CMPI DMARK
01600 BNE NOHED
01700
01800 LDXI 17
01900 GDIR: LDAZX FBUF ;Save first 16 bytes
02000 STAZX DBUF
02100 DEX
02200 BPL GDIR
00100 LDAZ SCNT ;Number of sectors in directory
00200 STAZ NSEC ;Wipe out NSEC
00300 LDYI 20 ;BLK Length
00400
00500 CKDIR: LDXI 0
00600
00700 CKNAM: LDAY FBUF
00800 CMPZX FBLK
00900 BNE NXTF
01000
01100 INY
01200 INX
01300 CPXI 12
01400 BNE CKNAM
01500 ;File names match so..
01600 LDAY FBUF ;Get file track number.
01700 STAZ FTRK
01800 LDAY 201 ;FBUF+1
01900 STAZ FSEC ;File sector number.
02000 LDAY 202 ;FBUF+2
02100 STAZ NSEC ;File length.
02200 TAX
02300 LDAI 0 ;File found.
02400 RTS
02500
02600 NXTF: TYA
02700 ORAI 17
02800 TAY
02900 INY ;Get next dir entry
03000 BPL CKDIR ;More in buffer
03100
03200 DECZ NSEC ;More sectors
03300 BEQ FNF
03400
03500 DEC FDSKS ;Next sector
03600 JSR RBUF
03700 BNE NOHED
03800 LDYI 0
03900 BEQ CKDIR
04000
04100 FNF: LDAI 200 ;Not in directory
04200 NOHED: RTS
00100 OPIN: JSR LOKUP ;Lookup file FNAM
00200 BNE RX ;File not found
00300
00400 SEEK: LDAZ FTRK ;Get track and sector
00500 STA FDSKD
00600 LDAZ FSEC
00700 STA FDSKS
00800 LDAI 340 ;Seek and verify command
00900 STA FDSKC
01000
01100 JSR FWAI ;Wait and read status
01200 EORI 177
01300 ANDI 354 ;Flush index bit, etc.
01400
01500 RX: RTS
01600
01700 ;Wait until not busy.
01800 FWAI: LDA FDSKC ;Read status
01900 LSRA
02000 BCC FWAI ;Check if busy
02100 RTS
02200
02300 SETTO: JSR FWAI ;Wait until not busy.
02400 SETT: LDYI 2 ;Setup time out interupt vector
02500 LDAI PLA
02600 ISET: STAY NMIV
02700 DEY
02800 BPL ISET
02900
03000 LDAI 377 ;Init timer
03100 STA RTCAH
03200 STA RTCAC
03300 RTS
00100 SETBUF: LDAI FBUF ;Read disk into FBUF
00200 STAZ FLAD ;Setup buffer pointer.
00300 ASLA ;Clear A
00400 STAZ 31 ;FLAD+1
00500 LDXI 1 ;X=1 For one sector
00600 RTS
00700
00800 RBUF: JSR SETBUF ;Setup address
00900
01000 ;Read sectors from disk.
01100 READ: JSR SETTO ;Wait and init time out.
01200 LDAI 143 ;IBM read command (n secs)
01300 STA FDSKC
01400
01500 RSEC: LDYI 0
01600 FLOAD: LDA DSKSEL ;Check if byte ready
01700 BPL FLOAD
01800 LDA FDSKD ;Read byte from disk
01900 STAIY FLAD
02000 INY
02100 BPL FLOAD
02200
02300 LDAZ FLAD
02400 EORI 200 ;Next sector
02500 STAZ FLAD
02600 BMI NOPAGE
02700 INCZ FLAD+1
02800
02900 NOPAGE: DEX
03000 BNE RSEC ;More sectors
03100
03200 JSR ENDSK ;Reset disk, timer. Read status
03300 RTS
03400
03500 ENDSK: LDAI 57 ;End disk op
03600 STA FDSKC
03700 STX RTCAC ;Disable timer
03800 TXA ;Wait for >12 cycles.
03900 DEX ;X = 377
04000 TXA
04100 EOR FDSKC ;Read disk status
04200 ANDI 376 ;For busy bit
04300 RTS
00100 ;Create file routine
00200 ENTR: STAZ FLEN ;Save file length.
00300 JSR LOKUP ;Check if file already exists.
00400 BEQ FEXIST ;Check if file exists
00500 CMPI 200 ;Not in dir. code
00600 BEQ GBLK
00700 FEXIST: LDAI 377 ;Return with error
00800 RTS
00900
01000 GBLK: LDAZ FFSEC ;Get first free sector
01100 SEC
01200 SBCZ FLEN ;Check if it fits on track
01300 CMPI 345
01400 BCS NOBUMP
01500 DECZ FFTRK
01600 LDAI 376
01700 STAZ FFSEC
01800 NOBUMP: LDAZ FFSEC
01900 STAZ FSEC
02000 LDAZ FFTRK
02100 STAZ FTRK
02200 JSR SEEK ;Point to new file
02300 BNE FEXIST ;Verify
02400 LDAI 377 ;Set write file open flag.
02500 STAZ WFOPEN
02600 LDAI 0 ;Return with no errors
02700 RTS
00100 LOC ZERO+100000 ;Display memory.
00200 ;Boot strap loader.
00300 BOOTS: JSR BWAI ;Wait until not busy.
00400 LDAI 244 ;Step track command
00500 STA FDSKC ;Step to track one.
00600
00700 LDAI 100 ;Load PCHR
00800 STAZ CUR
00900 LDAI 0
01000 STAZ CURH
01100 LDAI 357 ;PCHR sector number + 1.
01200 STA FDSKS
01300 JSR BOSEC ;Read a sector
01400 LDAI 0
01500 STAZ CUR
01600 LDAI 2
01700 STAZ CURH
01800 JSR BOSEC ;IRQV
01900 LDAI 200
02000 STAZ CUR
02100 JSR BOSEC
02200 LDAI 0
02300 STAZ CUR
02400 INCZ CURH
02500 JSR BOSEC
02600 LDAI 200
02700 STAZ CUR
02800 JSR BOSEC
02900 LDAI 0
03000 STAZ CUR
03100 LDAI 374
03200 STAZ CURH
03300 JSR BOSEC
03400 LDAI 200
03500 STAZ CUR
03600 JSR BOSEC
03700 JMP FBUF ;Jump to start up routine.
03800 BWAI: LDA FDSKC ;Read disk status.
03900 LSRA ;Get busy bit
04000 BCC BWAI
04100 RTS
04200 BOSEC: JSR BWAI
04300 DEC FDSKS ;Next sector
04400 LDYI 0
04500 LDAI 163 ;Read one sector command.
04600 STA FDSKC
04700 BOOLO: LDA DSKSEL ;Wait for byte from disk.
04800 BPL BOOLO
04900 LDA FDSKD ;Read byte
05000 STAIY CUR
05100 INY
05200 BPL BOOLO
05300 JSR BWAI
05400 EORI 177 ;Check for errors
05500 BNE WEDGE
05600 RTS
05700 WEDGE: JMP 177415 ;Error return to ddt.
00100 LOC ZERO+100200
00200 CLOCK: LDXI 2
00350 JSET: LDAZX CLKTBL-100000
00400 STAX NMIV
00500 DEX
00600 BPL JSET
00700
01000 LDAI 367
01100 STA RTCAH
01200 STA RTCAC
01300 PLA
01400 PLA
01500 PLA
01600 CLI
01700 JMP STOP
01750 CLKTBL: JMP CLOCK-100000
01800 CLKINT: PHA
01900 BIT RTCAC
02000 INC 100007
02200 LDA 100007
02300 CMPI 72
02400 BNE CRTN
02500 LDAI 60
02600 STA 100007
02700 INC 100006
02800 LDA 100006
02900 CMPI 66
03000 BNE CRTN
03100 LDAI 60
03200 STA 100006
03300 INC 100004
03400 LDA 100004
03500 CMPI 72
03600 BNE CRTN
03700 LDAI 60
03800 STA 100004
03900 INC 100003
04000 LDA 100003
04100 CMPI 66
04200 BNE CRTN
04300 LDAI 60
04400 STA 100003
04500 INC 100001
04600 LDA 100001
04700 CMPI 72
04800 BEQ TENH
04900 CMPI 62
05000 BNE CRTN
05100 LDA 100000
05200 CMPI 61
05300 BNE CRTN
05350 DEC 100000
05400 LDAI 61
05500 STA 100001
05600 BNE CRTN
05700 TENH: INC 100000
05800 CRTN: PLA
06100 RTI
00100 LOC ZERO+176000 ;SYS Ram
00200 WBUF: JSR SETBUF ;Write FBUF
00300
00400 WRITE: JSR SETTO ;Wait and init timer.
00500
00600 LDAI 103 ;Write multiple sectors command
00700 STA FDSKC
00800
00900 CLRY: LDYI 0
01000 WLOOP: LDA DSKSEL ;Wait until empty
01100 BPL WLOOP
01200
01300 LDAIY FLAD
01400 STA FDSKD ;Write chr on disk
01500 INY
01600 BPL WLOOP
01700
01800 QW: LDA DSKSEL ;Wait for 129th DRQ
01900 BPL QW
02000 STA FDSKD
02100
02200 LDAZ FLAD
02300 EORI 200 ;Next sector
02400 STAZ FLAD
02500 BMI CKMOR
02600 INCZ FLAD+1
02700 CKMOR: DEX ;More sectors
02800 BNE CLRY
02900
03000 JSR ENDSK ;Reset disk, timer. Read status
03100 BNE WERR ;Verify if no errors
00100 ;Verify disk write
00200 VERIFY: LDAZ FSEC ;Reset disk sector number
00300 STA FDSKS
00400 JSR SETT ;Set timer
00500 LDXZ NSEC ;Get number of sectors
00600 LDAI 147 ;Read MS, HE.
00700 STA FDSKC
00800
00900 NXTS: LDYI 0
01000 VWAI: LDA DSKSEL ;Wait for byte
01100 BPL VWAI
01200 LDA FDSKD ;Reset DRQ.
01300 INY
01400 BPL VWAI ;Done with sector
01500
01600 DEX
01700 BNE NXTS ;Done with file
01800
01900 JSR ENDSK ;Reset disk, timer. Read status
02000 WERR: RTS ;Return with error bits
00100 CLOZE: BITZ WFOPEN ;Check if file open
00200 BMI UPDIR
00300 RERR: LDAI 377 ;Return with error
00400 RTS
00500
00600 ;Update directory
00700 UPDIR: LDAI 377 ;Get end of directory
00800 STAZ FTRK
00900 LDXZ SCNT ;Get sec.
01000 INX
01100 TXA
01200 EORI 377 ;Invert it
01300 STAZ FSEC
01400 STAZ OSEC
01500 JSR SEEK
01600 BNE RERR ;Seek error
01700 JSR RBUF ;Read end of directory.
01800 BNE RERR ;Read error
01900
02000 LDAZ FFTRK ;Point to new file
02100 STAZ FTRK
02200 LDAZ FFSEC
02300 STAZ FSEC
02400
02500 LDXZ FFDIR
02600
02700 ;BLT FBLK into directory
02800 LDYI 0
02900 NAMEIT: LDAY FBLK
03000 STAZX FBUF
03100 INX
03200 INY
03300 CPYI 20 ;FBLK Length
03400 BNE NAMEIT
03500
03600 LDXZ OSEC ;Point to end of directory
03700 STXZ FSEC
03800
03900 STX FDSKS
04000 LDXI 1 ;For one sector
04100 STXZ NSEC
04200 JSR WBUF ;Write new file record
04300 BNE RERR ;Check for write error
04400
04500 CLC
04600 LDAZ FFDIR
04700 ADCI 20 ;Update end of dir.
04800 BPL SVSEC
04900 LDAI 0
05000 INCZ SCNT ;Next sector
05100
05200 SVSEC: STAZ FFDIR
05300
05400 LDAZ FFSEC
05500 SEC
05600 SBCZ FLEN ;Point to next free sector.
05700 STAZ FFSEC
05800
05900 LDAI 375 ;Point to header.
06000 STAZ FSEC
06100 STA FDSKS ;Start of directory
06200 JSR RBUF ;Read directory header
06300 BNE RERR ;Check for read error
06400
06500 LDXI 1
06600 STXZ NSEC
06700 LDXI 17 ;Header length
06800 HLOOP: LDAZX DBUF ;BLT Header into directory
06900 STAZX FBUF
07000 DEX
07100 BPL HLOOP
07200
07300 JSR WBUF ;Write directory
07400 BNE RERR ;Write error
07500 STAZ WFOPEN ;Reset write file open flag
07600
07700 RTS
00100 PIT: LDYI 0
00200 STAIY CUR ;Print chr on screen
00300 INCZ CUR
00400 LDAZ CUR
00500 ANDI 77
00600 BNE UPCUR ;Update cursor
00700 DECZ CUR ;Fix <cr>.
00800 LDAZ CUR
00900 ANDI 300 ;<cr>
01000 STAZ CUR
01100 JMP LF ;New line
01200
01300 BS: DECZ CUR ;Back space.
01400 UPCUR: LDAZ CUR ;Update cursor
01500 STA DCURL
01600 LDAZ CURH
01700 STA DCURH
01800 RTS
01900
02000 BLOCK 200 ;Zeros
02100 END